﻿Public Class PrimTahsilat : Inherits Process

	Dim isyerino, sno, donem, bordro, islemtar As Input
	Dim WithEvents Grid1 As Grid
	Dim WithEvents Grid2 As Grid
	Dim Rsi As Recordset
	Dim Asgari, MinPrim, MaxPrim As Decimal
	Dim Toolstrip As ToolStrip
	Dim DonemeEsasTarih As Date = Today.AddMonths(-1).AddDays(-Today.Day + 1)
	Dim FileOpenDialog As New OpenFileDialog With {.Title = "Dosya aç...", .Filter = "Bordro dosyaları|*~*~*.txt|Metin dosyaları|*.txt|Tüm dosyalar|*.*"}
	Dim FolderOpenDialog As New FolderBrowserDialog With {.Description = "Klasör aç..."}
	Dim USBDialog As Dialog

	Dim Tab As Integer = 0
	Dim Borc As Prim.Borc.Borc

	Public Overrides Sub GenericEvent(ByVal e As ProcessEventArgs)
		If Toolstrip Is Nothing Then
			Toolstrip = New ToolStrip
			Toolstrip.Dock = DockStyle.Top
			Toolstrip.AddButtonGroup("tab", "page0", "&1.Kurum", My.Resources.editing)
			Toolstrip.AddButtonGroup("tab", "page1", "&2.Kişi", My.Resources.editing)
			Toolstrip.AddButton("folder>", "&Klasör aç", My.Resources.bwfolder)
			Toolstrip.AddButton("file>", "&Dosya aç", My.Resources.bwreport)
			Toolstrip.AddButton("ftp>", "&FTP dizini", My.Resources.network)
			Toolstrip.AddButton("-usb>", "&USB/CD", My.Resources.usb)
			Toolstrip.Padding = New Padding(2, 2, 2, 3)
			Controls.Add(Toolstrip)
			Toolstrip.BringToFront()
			Toolstrip.Items("page0").PerformClick()
			MainPanel.BringToFront()
		End If
		Select Case Tab
			Case 0 : GenericEventKurum(e)
			Case 1 : GenericEventKisi(e)
		End Select
	End Sub

	Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, keyData As System.Windows.Forms.Keys) As Boolean
		If keyData = Keys.Alt + Keys.E Then
			ShowDialog("Emanet")
			Return True
		End If
		If keyData = Keys.Alt + Keys.C Then
			ShowDialog("Open", "usb")
			Return True
		End If
		If CurrentRegion Is Region0 Then
			If keyData = Keys.PageDown Then
				Toolstrip.GroupSwitch("tab", True)
				Return True
			ElseIf keyData = Keys.PageUp Then
				Toolstrip.GroupSwitch("tab", False)
				Return True
			End If
		End If
		Return MyBase.ProcessCmdKey(msg, keyData)
	End Function

	Dim EkMesai As Boolean

	Private Sub Import(File As String)
		Dim Info = ParseFileName(My.Computer.FileSystem.GetName(File))
		ShowProgress()
		Progress.ReportProgress("İşyeri bilgileri okunuyor...")
		isyerino.Set(Info.isyerino)
		bordro.Set(Info.bordro)
		donem.Set(Info.yil & Info.ay.n2)
		ValidateForm()
		List.Focus()
		List.Clear()
		'Dosyayı oku ve listeyi doldur
		Progress.ReportProgress("Dosya okunuyor...")
		Dim Text = FileSystem.ReadFileContents(File)
		Dim Rows As New List(Of DataGridViewRow)
		Dim Sno As New List(Of Integer)
		For Each c In From l In Split(Text, vbCrLf) Where l <> "" Select x = Split(l, ",") Where x.Length >= 6
			Dim Row = AddRow()
			Row.Visible = False
			Rows.Add(Row)
			Row.SetValues("", c(0), c(1), c(2), c(3), Trim(c(2)) & " " & Trim(c(3)), CDec(c(5)), c(4))
			If IsNumeric(c(0)) AndAlso Not Sno.Contains(c(0)) Then Sno.Add(c(0))
		Next
		EkMesai = Not (From r In List.Rows Where r.Cells("pogs").Value <> 0).Any
		AddRssno(Sigortali.SnoAraListe(Remote, Sno, Mid(isyerino.Get, 1, 1)))
		Progress.ReportProgress("Kayıtlar kontrol ediliyor...", Grid1.Rows.Count)
		IsBatch = True
		For Each Row In Grid1.Rows
			CheckRow(Row)
			Progress.Inc()
			Row.Visible = True
		Next
		IsBatch = False
		ShowErrorStatus()
		Progress.Close()
		List.Focus()
		UpdateSummary()
	End Sub

	Dim RowsToCorrect As List(Of DataGridViewRow)

	Sub Correct()
		RowsToCorrect = (From r As DataGridViewRow In Grid1.Rows Where r.Visible And r.Tag <> "").ToList
		If RowsToCorrect.Any Then ShowDialog("Correct")
	End Sub

	Public Overrides Sub DialogEvent(e As ProcessEventArgs)
		Select Case Modal.Name
			Case "Open" : DialogOpen(e)
			Case "Correct" : DialogCorrect(e)
			Case "Emanet" : DialogEmanet(e)
			Case "Isyeri" : DialogIsyeri(e)
		End Select
	End Sub

	Function AddRow() As DataGridViewRow
		Grid1.Rows.Add()
		Grid1.CurrentCell = Grid1.Rows(Grid1.Rows.Count - 1).Cells("sno")
		Return Grid1.Rows(Grid1.Rows.Count - 1)
	End Function

	Function ShowResults(tur As String, Value As Object, Row As DataGridViewRow) As Boolean
		If tur = "kimlik" Then
			Rs = Sigortali.KimlikAra(Local, Value)
			If Not Rs.EOF Then
				If (From r As DataGridViewRow In Grid1.Rows Where Not r Is Row AndAlso r.Cells("sno").Value = Rs("sno")).Any Then
					Warning("Bu şahıs daha önce girilmişti.")
					Return False
				End If
			End If
			Row.Cells("sno").Value = ""
		Else
			Rs = Sigortali.SnoAra(Local, Value)
			If Not Rs.EOF Then
				If (From r As DataGridViewRow In Grid1.Rows Where Not r Is Row AndAlso r.Cells("sno").Value = Rs("sno")).Any Then
					Warning("Bu şahıs daha önce girilmişti.")
					Return False
				End If
			End If
			Row.Cells("kimlik").Value = ""
		End If
		Row.Cells("adi").Value = ""
		Row.Cells("pasaport").Value = ""
		If Not Rs.EOF Then
			AddRssno(Rs)
			Row.Cells("kimlik").Value = Rs("kimlik")
			Row.Cells("sno").Value = Rs("sno")
			Row.Cells("adi").Value = Trim(Rs("adi"))
			Row.Cells("soyadi").Value = Trim(Rs("soyadi"))
			Row.Cells("adisoyadi").Value = Trim(Rs("adi") & " " & Rs("soyadi"))
			Row.Cells("pasaport").Value = Rs("pasaport")
			If Row.Cells("pek").Value Is Nothing Then Row.Cells("pek").Value = MinPrim
			Row.Cells("pogs").Value = 30
		End If
		CheckRow(Row)
		UpdateSummary()
		Return Not Rs.EOF
	End Function

	Private Sub Grid_CellValidating(sender As Object, e As System.Windows.Forms.DataGridViewCellValidatingEventArgs) Handles Grid1.CellValidating
		Dim Cell = Grid1.Rows(e.RowIndex).Cells(e.ColumnIndex)
		If Not Grid1.IsCurrentCellDirty Then Return
		Select Case Cell.OwningColumn.Name
			Case "kimlik"
				ShowResults("kimlik", Grid1.EditingControl.Text, Cell.OwningRow)
			Case "sno"
				ShowResults("sno", Grid1.EditingControl.Text, Cell.OwningRow)
		End Select
	End Sub

	Private Sub SetError(Row As DataGridViewRow, ErrCode As String, Icon As String, Message As String)
		Row.Cells("durum").Value = "[" & Icon & "]"
		Select Case Icon
			Case "x" : Row.DefaultCellStyle.BackColor = Mix(Color.Red, Color.White, 85)
			Case "!" : Row.DefaultCellStyle.BackColor = Mix(Color.Yellow, Color.White, 85)
			Case Else : Row.DefaultCellStyle.BackColor = Color.White
		End Select
		If Icon <> "/" Then Row.Cells("acik").Value = Message
		Row.Tag = ErrCode
		ShowErrorStatus()
	End Sub

	Dim IsBatch As Boolean

	Sub ShowErrorStatus()
		If IsBatch Then Return
		Dim a(3) As Integer
		a(0) = (From r As DataGridViewRow In Grid1.Rows Where r.Cells("durum").Value > "").Count
		a(1) = (From r As DataGridViewRow In Grid1.Rows Where r.Cells("durum").Value = "[x]").Count
		a(2) = (From r As DataGridViewRow In Grid1.Rows Where r.Cells("durum").Value = "[!]").Count
		a(3) = (From r As DataGridViewRow In Grid1.Rows Where r.Cells("durum").Value = "[i]").Count
		List.Buttons("ok").Text = a(0) & " &kayıt"
		List.Buttons("error").Text = a(1) & " &hata"
		List.Buttons("warning").Text = a(2) & " uyarı"
		List.Buttons("info").Text = a(3) & " bilgi"
		List.Buttons("ok").Visible = True
		List.Buttons("error").Visible = a(1) > 0
		List.Buttons("warning").Visible = a(2) > 0
		List.Buttons("info").Visible = a(3) > 0
		Dim CorrectableErrors = "sno.invalid;kimlik.sno.mismatch;invalid.pogs.30;pogs.overflow;pek.underflow;pek.overflow".Split(";")
		Dim AnyCorrectableErrors = (From r As DataGridViewRow In Grid1.Rows Where r.Cells("durum").Value = "[x]" AndAlso (From c In CorrectableErrors Where CStr(r.Tag).StartsWith(c)).Any).Any
		List.Buttons("correct").Enabled = AnyCorrectableErrors
	End Sub

	Dim Rssno As New SortedList(Of Integer, DataRow)
	Dim bordrotar As Date

	Private Sub CheckRow(Row As DataGridViewRow)
		Row.Cells("acik").Value = ""
		Dim sno = Row.Cells("sno").Value
		Dim kimlik = Trim(Row.Cells("kimlik").Value)
		Dim pogs = Row.Cells("pogs").Value
		'Sigortalı var mı kontrolü
		If (Trim(sno) = "" OrElse Not Rssno.ContainsKey(sno)) Then
			If Row.Cells("sno").FormattedValue = "" Then
				SetError(Row, "sno.invalid", "x", "Sigorta numarası bulunamadı.")
				Return
			End If
			If Row.Cells("kimlik").FormattedValue = "" Then
				SetError(Row, "kimlik.invalid", "x", "Kimlik numarası bulunamadı.")
				Return
			End If
			SetError(Row, "sno.invalid", "x", "Sigorta numarası bulunamadı.")
			Return
		End If
		'Sigorta numarası kimlik ile uyumlu mu?
		If Trim(Rssno(sno)("kimlik")) <> kimlik Then
			SetError(Row, "kimlik.sno.mismatch", "x", "Kimlik sigorta numarasıyla eşleşmiyor.")
			Return
		End If
		'Sigortalı bu kurumda çalıştı mı?
		If Not (From g In sigc Where g.sno = sno).Any Then
			SetError(Row, "sigc.invalid", "x", "Bu işyerinde çalışmıyor.")
			Return
		End If
		'Sigortalı bu tarihlerde çalıştı mı?
		If Not (From g In sigc Where g.sno = sno Where g.ciktar >= bordrotar And g.girtar < bordrotar.AddMonths(1)).Any() Then
			SetError(Row, "sigc.invalid", "x", "Bu işyerinde çalışmıyor.")
			Return
		End If
		'Statüsü bordro tipi ile uyumlu mu?
		If (Len(bordro.Get) = 1 AndAlso Row.Cells("sno").Value > 99999999) OrElse (Len(bordro.Get) = 2 AndAlso sno < 99999999) Then
			SetError(Row, "bordro.invalid", "x", "Sigorta no. bordro tipi ile uyumlu değil.")
			Return
		End If
		'Prime esas kazanç kontrolü
		If Row.Cells("pek").Value <= 0 Then
			SetError(Row, "invalid.pek", "x", "Prime esas kazanç 0 olamaz.")
			Return
		End If
		'Gün sayısı kontrolü
		If EkMesai Then
			If Row.Cells("pogs").Value <> 0 Then
				SetError(Row, "invalid.pogs.0", "x", "Prim ödeme gün sayısı 0 olmalıdır.")
				Return
			End If
		Else
			If Row.Cells("pogs").Value <= 0 Then
				SetError(Row, "invalid.pogs.0", "x", "Prim ödeme gün sayısı 0 olamaz.")
				Return
			End If
			If Row.Cells("pogs").Value > 30 Then
				SetError(Row, "invalid.pogs.30", "x", "PÖGS 30'dan fazla olamaz.")
				Return
			End If
		End If
		'Emeklilik kontrolü
		If bordro.Get = "D" Then
			Dim igc = (From g In sigc Where g.kimlik = kimlik).FirstOrDefault
			If Not igc Is Nothing AndAlso Not IsNull(igc.ymbastar) AndAlso igc.ymbastar <= bordrotar Then
				SetError(Row, "bordro.invalid.e", "x", "İlgili dönemde yaşlılık maaşı alır.")
				Return
			End If
		End If
		If bordro.Get = "E" Then
			Dim igc = (From g In sigc Where g.kimlik = kimlik).First
			If IsNull(igc.ymbastar) OrElse igc.ymbastar > bordrotar Then
				SetError(Row, "bordro.invalid.d", "x", "İlgili dönemde yaşlılık maaşı almaz.")
				Return
			End If
		End If
		'Gün sayısını kontrolü
		Dim songun = bordrotar.AddMonths(1).AddDays(-1)
		Dim CalistigiGunler = GetDates(bordrotar, songun, (From g In sigc Where g.sno = sno Select New Interval(g.girtar, g.ciktar)).ToList)
		Dim AyGunSayisi = songun.Day
		Dim TamAy = CalistigiGunler.Count = AyGunSayisi
		Dim MaxGunSayisi As Integer = If(TamAy, 30, Math.Min(CalistigiGunler.Count, 30))
		If pogs > MaxGunSayisi Then
			If MaxGunSayisi = 0 Then
				SetError(Row, "pogs.overflow?" & MaxGunSayisi, "x", "Yatırımı tamamdır.")
			Else
				SetError(Row, "pogs.overflow?" & MaxGunSayisi, "x", "En çok " & MaxGunSayisi & " günlük yatırım yapabilir.")
			End If
			Return
		End If
		If Not EkMesai Then
			Dim tpogs = (From p In shesk Where p.sno = sno Select g = p.pogs).Sum
			If tpogs > 0 Then
				MaxGunSayisi -= tpogs
				If pogs > MaxGunSayisi Then
					If MaxGunSayisi = 0 Then
						SetError(Row, "pogs.overflow?" & MaxGunSayisi, "x", "Yatırımı tamamdır.")
					Else
						SetError(Row, "pogs.overflow?" & MaxGunSayisi, "x", "En çok " & MaxGunSayisi & " günlük yatırım yapabilir.")
					End If
					Return
				End If
			End If
		End If
		'Çalışma izni kontrolü
		If Not (kimlik.Length = 6 And kimlik < "600000") Then
			Dim izinler = (From c In scalisma Where c.sno = sno Select New Interval(c.bastar, c.bittar)).ToList
			Dim CalismaIzinliGunler As List(Of Date) = GetDates(bordrotar, songun, izinler)
			If CalistigiGunler.Except(CalismaIzinliGunler).Any Then
				'Hiç izni var mı?
				If Not izinler.Any Then
					SetError(Row, "permit.none", "x", "Çalışma izni yoktur.")
					Return
				End If
				Dim son = (From c In izinler Order By c.tarih2 Descending).FirstOrDefault.tarih2
				'İznin bitmesinden sonra 3 ay geçti mi?
				If son < bordrotar.AddMonths(-3) Then
					SetError(Row, "permit.invalid?" & son.DMY, "x", "Çalışma izni " & son.DMY & " tarihinde bitmiştir.")
					Return
				End If
				SetError(Row, "permit.overflow?" & son.DMY, "!", "Çalışma izni " & son.DMY & " tarihinde bitmiştir.")
				Return
			End If
		End If
		'PEK kontrolü
		Dim minp = Math.Round(MinPrim / 30 * If(EkMesai, 30, pogs), 2)
		Dim maxp = Math.Round(MaxPrim / 30 * If(EkMesai, 30, pogs), 2)
		If Row.Cells("pek").Value < minp Then
			SetError(Row, "pek.underflow?" & minp, "x", "PEK en az " & Fm(minp) & " olmalıdır.")
			Return
		End If
		If Row.Cells("pek").Value > maxp Then
			SetError(Row, "pek.overflow?" & maxp, "x", "PEK en fazla " & Fm(maxp) & " olmalıdır.")
			Return
		End If
		If Not EkMesai Then
			'Raporlu günleri bul
			Dim RaporluGunler = GetDates(bordrotar, songun, (From r In srapor Where r.sno = sno Select New Interval(r.bastar, r.bittar)).ToList)
			'Eksik veya fazla yatırım yapma uyarısı
			Dim Expl = ""
			Dim yggs = Math.Min(30, CalistigiGunler.Except(CalistigiGunler.Intersect(RaporluGunler)).Count)
			If pogs < yggs Then
				Expl &= " " & (yggs - pogs) & " gün eksik yatırım yapılıyor."
			ElseIf pogs > yggs AndAlso yggs <> AyGunSayisi Then
				Expl &= " " & (pogs - yggs) & " gün fazla yatırım yapılıyor."
			End If
			If RaporluGunler.Intersect(CalistigiGunler).Any Then
				Dim rpr = ""
				For Each rapor In (From r In srapor Where r.sno = sno)
					rpr &= ", " & rapor.tur & " (" & rapor.bastar.DMY & "-" & rapor.bittar.DMY & ")"
				Next
				Expl &= " Ay içinde " & Mid(rpr, 3) & " raporu vardır."
			End If
			Expl = Mid(Expl, 2)
			If Expl <> "" Then
				SetError(Row, "report", "i", Expl)
				Return
			End If
		End If
		SetError(Row, "", "/", "")
	End Sub

	Private Sub AddRssno(Rs As Recordset)
		For Each Row In Rs.Rows
			If Rssno.ContainsKey(Row("sno")) Then Rssno.Remove(Row("sno"))
			Rssno.Add(Row("sno"), Row)
		Next
	End Sub

	Private Sub Grid_RowValidating(sender As Object, e As System.Windows.Forms.DataGridViewCellCancelEventArgs) Handles Grid1.RowValidating
		If Not Grid1.IsCurrentRowDirty Then Return
		CheckRow(Grid1.Rows(e.RowIndex))
		UpdateSummary()
	End Sub

	Private Sub RemoveRow(RowToRemove As DataGridViewRow)
		RowToRemove.Visible = False
	End Sub

#Region " Data structures "

	Dim sigc As New List(Of igc)
	Dim scalisma As New List(Of calisma)
	Dim srapor As New List(Of rapor)
	Dim shesk As New List(Of hesk)

	Private Sub IsyeriBilgileriniOku(isyerino As String)
		sigc.Clear()
		Rs = Isyeri.TumCalisanlar(Remote, isyerino)
		For Each Row In Rs
			Dim igc As New igc
			igc.kimlik = Trim(Rs("kimlik"))
			igc.sno = Rs("sno")
			igc.adi = Rs("adi1")
			igc.soyadi = Rs("soyadi1")
			igc.girtar = Rs("girtar")
			igc.ciktar = IsNull(Rs("ciktar"), "2099/12/31")
			sigc.Add(igc)
		Next
		Rs = Isyeri.Bordro.TumEmekliCalisanlar(Remote, isyerino)
		For Each Row In Rs
			For Each igc In (From g In sigc Where Trim(g.kimlik) = Trim(Rs("kimlik")))
				igc.ymbastar = CDate(IsNull(Rs("ymbastar"), "1976/01/01"))
			Next
		Next
		scalisma.Clear()
		Rs = Isyeri.Bordro.CalismaIzni(Remote, isyerino)
		For Each Row In Rs
			Dim calisma As New calisma
			calisma.sno = Rs("sno")
			calisma.kimlik = Trim(Rs("kimlik"))
			calisma.bastar = Rs("izinbastar")
			calisma.bittar = Rs("izinsontar")
			scalisma.Add(calisma)
		Next
		srapor.Clear()
		Rs = Isyeri.Bordro.Rapor(Remote, isyerino, bordrotar)
		For Each Row In Rs
			Dim rapor As New rapor
			rapor.sno = Rs("sno")
			rapor.kimlik = Trim(Rs("kimlik"))
			Select Case Rs("tur")
				Case "a" : rapor.tur = "Analık"
				Case "i" : rapor.tur = "İşkazası"
				Case "h" : rapor.tur = "Hastalık"
			End Select
			rapor.bastar = Rs("bastar")
			rapor.bittar = Rs("bittar")
			srapor.Add(rapor)
		Next
		shesk.Clear()
		'***********************************'
		Rs = Isyeri.Bordro.Yatirim(Local, isyerino, bordrotar)
		For Each Row In Rs
			Dim prim As New hesk
			prim.sno = Rs("sno")
			prim.kimlik = Trim(Rs("kimlik"))
			prim.pogs = Rs("pogs")
			shesk.Add(prim)
		Next

	End Sub

	Class igc

		Public kimlik As String
		Public sno As Integer
		Public adi As String
		Public soyadi As String
		Public girtar As Date
		Public ciktar As Date
		Public ymbastar As Date?

	End Class

	Class calisma

		Public kimlik As String
		Public sno As Integer
		Public bastar As Date
		Public bittar As Date

	End Class

	Class rapor

		Public kimlik As String
		Public sno As Integer
		Public tur As String
		Public bastar As Date
		Public bittar As Date

	End Class

	Class hesk

		Public kimlik As String
		Public sno As Integer
		Public pogs As Integer

	End Class

	Private Function GetDates(tarih1 As Date, tarih2 As Date, intervals As List(Of Interval)) As List(Of Date)
		Dim List As New List(Of Date)
		For Each interval In intervals
			Dim t1 = tarih1, t2 = tarih2
			If interval.tarih1 > tarih1 Then t1 = interval.tarih1
			If interval.tarih2 < tarih2 Then t2 = interval.tarih2
			For i = 0 To DateDiff(DateInterval.Day, t1, t2)
				If Not List.Contains(t1) Then List.Add(t1)
				t1 = t1.AddDays(1)
			Next
		Next
		Return List
	End Function

	Class Interval
		Public tarih1 As Date
		Public tarih2 As Date

		Sub New(tarih1 As Date, tarih2 As Date)
			Me.tarih1 = tarih1
			Me.tarih2 = tarih2
		End Sub
	End Class

#End Region

#Region " Dialog Open "

	Dim ProgressLabel As Windows.Forms.Label
	Dim DateFilter As String = ""

	Private Sub DialogOpen(e As ProcessEventArgs)
		Select Case e.EventType
			Case EventType.Initialize
				Modal.Start("İşyeri prim tahsilatı", "Dosya seçin.")
				Modal.AddList("", 720, 360)
			Case EventType.Shown
				Modal.List.AddColumns("file(h),isyeriadi(İşyeri adı;100%l),isyerino(İşyeri no.;100c),bordro(Bordro;80c),bordrotar(Bordro tar.;100c),tutar(Tutar;80m)")
				Modal.List.AutoFilter = "isyeriadi,isyerino,bordro,bordrotar"
				Modal.List.AutoNavigate = True
				Modal.Buttons.Show("Next")
				Select Case Modal.Arguments("Arg")
					Case "usb" : ExploreUSB()
					Case Else : ExplorePath()
				End Select
			Case EventType.Activate, EventType.Save
				If Modal.List.NoSelection Then Return
				Dim File = Modal.List.SelectedRow("file")
				DateFilter = Modal.List.Columns("bordrotar").Tag
				Close()
				Import(File)
			Case EventType.Progress
				Dim File As String = e.Tag
				Try
					If Mid(File, 1, 1) = "!" Then
						ProgressLabel.Text = Mid(File, 2)
						Return
					End If
					Dim Info = ParseFileName(My.Computer.FileSystem.GetName(File))
					Modal.List.AddRow(File, Info.isyeriadi, FormatIsyeriNo(Info.isyerino), Info.bordro, Info.yil & "/" & Info.ay.n2, CDec(Info.tutar))
				Catch ex As Exception
					Application.DoEvents()
				End Try
			Case EventType.AsyncCompleted
				Select Case Modal.Arguments("Arg")
					Case "usb" : Modal.Help = "USB içerisindeki dosyalar listelenmiştir."
					Case Else : Modal.Help = "Klasör içerisindeki dosyalar listelenmiştir."
				End Select
				Modal.List.Columns("bordrotar").Tag = If(DateFilter <> "", DateFilter, "filter:" & DonemeEsasTarih.ToString("yyyy/MM"))
				Modal.List.ApplyFilter()
				Modal.List.Sort(Modal.List.Columns("bordrotar"), System.ComponentModel.ListSortDirection.Descending)
				Modal.List.SelectFirst()
				Modal.List.BottomPanel.Hide()
		End Select
	End Sub

	Sub ExploreUSB()
		Modal.List.BottomPanel.Height = 45
		ProgressLabel = New Windows.Forms.Label
		Modal.List.BottomPanel.Controls.Add(ProgressLabel)
		ProgressLabel.Padding = New Padding(14)
		ProgressLabel.Anchor = AnchorStyles.Left
		ProgressLabel.Dock = DockStyle.Fill
		ProgressLabel.Text = "USB çıkarılabilir bellekler okunuyor. Lütfen bekleyin..."
		Modal.List.BottomPanel.Visible = True
		Modal.AsyncRun(AddressOf ExploreUSBDrives)
	End Sub

	Sub ExplorePath()
		Modal.List.BottomPanel.Height = 45
		ProgressLabel = New Windows.Forms.Label
		Modal.List.BottomPanel.Controls.Add(ProgressLabel)
		ProgressLabel.Padding = New Padding(14)
		ProgressLabel.Anchor = AnchorStyles.Left
		ProgressLabel.Dock = DockStyle.Fill
		ProgressLabel.Text = "Klasör okunuyor. Lütfen bekleyin..."
		Modal.List.BottomPanel.Visible = True
		Modal.AsyncRun(AddressOf ExploreFolders)
	End Sub

	Sub ExploreFolders()	'Async
		Modal.AsyncProgress(-1, "!Klasör araştırılıyor, lütfen bekleyin...")
		Explore(Modal.Arguments("Arg"))
	End Sub

	Sub ExploreUSBDrives() 'Async
		For Each Drive In (From d In My.Computer.FileSystem.Drives Where d.DriveType = IO.DriveType.Removable)
			If Drive.IsReady Then
				Dim Label = Drive.VolumeLabel
				If Label = "" Then Label = "Çıkarılabilir bellek"
				Modal.AsyncProgress(-1, "!" & Drive.VolumeLabel & " (" & Mid(Drive.Name, 1, 2) & ") araştırılıyor, lütfen bekleyin...")
				Explore(Drive.Name)
			End If
			If AsyncCancelled Then Return
		Next
	End Sub

	Sub Explore(Path As String) 'Async
		Try
			Dim f = My.Computer.FileSystem.GetFiles(Path, FileIO.SearchOption.SearchTopLevelOnly)
			For Each File In f
				If GetFileFormat(File) > 0 Then Modal.AsyncProgress(0, File)
				If AsyncCancelled Then Return
			Next
		Catch ex As Exception
		End Try
		For Each Folder In My.Computer.FileSystem.GetDirectories(Path)
			Explore(Folder)
			If AsyncCancelled Then Return
		Next
	End Sub

	Dim FileFormats = "*~*~*.txt;*-*-*-*.txt;??????.???.*.txt".Split(";")
	Function GetFileFormat(File As String) As Integer
		Dim i As Integer = 0
		For Each f In FileFormats
			i += 1
			If File Like f Then Return i
		Next
		Return 0
	End Function

	Class ParsedFileInfo
		Friend isyerino As String
		Friend bordro As String
		Friend ay As Integer
		Friend yil As String
		Friend tutar As String
		Friend isyeriadi As String
	End Class

	Function ParseFileName(File As String) As ParsedFileInfo
		Dim Info = New ParsedFileInfo
		Select Case GetFileFormat(File)
			Case 1
				Dim Data = My.Computer.FileSystem.GetName(File).Split("~")
				Info.isyerino = Mid(Data(1), 1, 1) & Mid(Data(1), 3, 5)
				Info.bordro = Mid(Data(1), 8)
				Info.ay = CInt(Mid(Data(2), 1, 2))
				Info.yil = Mid(Data(2), 3, 4)
				Info.tutar = Data(3)
				Info.isyeriadi = Data(0)
			Case 2
				Dim Data = My.Computer.FileSystem.GetName(File).Split("-")
				Info.isyerino = Mid(Data(1), 1, 1) & Mid(Data(1), 8, 5)
				Info.isyeriadi = Data(0)
				Dim Pos = InStrRev(Data(1), "_")
				Info.bordro = Mid(Data(1), Pos + 1)
				Info.ay = CInt(Mid(Data(2), 1, 2))
				Info.yil = Mid(Data(2), 3, 4)
				Info.tutar = Data(3)
			Case 3
				Dim Data = My.Computer.FileSystem.GetName(File).Split(".")
				Info.isyerino = "100" & Data(1)
				Info.isyeriadi = "BELEDİYE"
				Info.bordro = Data(2)
				Info.ay = Mid(Data(0), 5, 2)
				Info.yil = Mid(Data(0), 1, 4)
				Info.tutar = Data(1)
		End Select
		Info.isyerino = Info.isyerino.Replace("I", "1")
		Info.tutar = Info.tutar.Replace(".txt", "").Replace(".", "").Replace(",", "")
		If Len(Info.tutar) > 2 Then Info.tutar = Mid(Info.tutar, 1, Info.tutar.Length - 2) & "." & Info.tutar.Right(2)
		Return Info
	End Function

#End Region

#Region " Dialog Correct "

	Private Sub DialogCorrect(e As ProcessEventArgs)
		Select Case e.EventType
			Case EventType.Initialize
				Modal.AddList("List", 850, 400)
				Modal.List.AddColumns("^correct(;24l),durum(;25c),sirano(;40c),sno(Sigorta no.;80l),kimlik(Kimlik no.;80l)")
				Modal.List.AddColumns("adi(Adı;30%l),pek(PEK;80m),pogs(PÖGS;50n),aciklama(Açıklama;40%l)")
			Case EventType.Shown
				Modal.List.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells
				Modal.List.DefaultCellStyle.Padding = New Padding(3, 2, 3, 2)
				For Each r In RowsToCorrect
					Modal.List.Rows.Add()
					Dim Row = Modal.List.Rows(Modal.List.RowCount - 1)
					Row.Visible = False
					Row.Cells("sirano").Value = r.Index + 1
					Row.Cells("sno").Value = r.Cells("sno").Value
					Row.Cells("kimlik").Value = r.Cells("kimlik").Value
					Row.Cells("adi").Value = r.Cells("adisoyadi").Value
					Row.Cells("pek").Value = r.Cells("pek").Value
					Row.Cells("pogs").Value = r.Cells("pogs").Value
					Dim Corrected = False
					Dim Items = Split(r.Tag, "?")
					Dim kimlik = Trim(Row.Cells("kimlik").Value)
					Dim sno = Trim(Row.Cells("sno").Value)
					Dim adi = Trim(Row.Cells("adi").Value)
					Select Case Items(0)
						Case "sno.invalid"
							If Not Corrected Then
								Dim Rsk = Sigortali.KimlikAra(Local, kimlik)
								If Not Rsk.EOF AndAlso Difference(Trim(Rsk("adi")) & " " & Trim(Rsk("soyadi")), adi) < 0.1 Then
									FixCell(Row, "sno", Rsk("sno"), "Sigorta numarası düzeltildi.")
									AddRssno(Rsk)
									Corrected = True
								End If
							End If
							If Not Corrected And IsNumeric(sno) Then
								Dim f = (From g In sigc Let d = Difference(g.adi & " " & g.soyadi, adi) Where d < 0.1 Order By d Select g)
								If (From c In f Select a = c.sno).Distinct.Count > 0 Then
									If sno <> f.First.sno AndAlso kimlik <> f.First.kimlik Then
										FixCell(Row, "sno", f.First.sno, "Sigorta numarası düzeltildi.")
										FixCell(Row, "kimlik", f.First.kimlik, "Kimlik ve sigorta numarası düzeltildi.")
										'AddRssno(Rsk)
										Corrected = True
									ElseIf sno <> f.First.sno Then
										FixCell(Row, "sno", f.First.sno, "Sigorta numarası düzeltildi.")
										Corrected = True
									Else
										FixCell(Row, "kimlik", f.First.kimlik, "Kimlik numarası düzeltildi.")
										Corrected = True
									End If
								End If
							End If
						Case "kimlik.sno.mismatch"
							If Not Corrected Then
								Dim Rss = Sigortali.SnoAra(Local, sno)
								If Not Rss.EOF AndAlso Difference(Trim(Rss("adi")) & " " & Trim(Rss("soyadi")), adi) < 0.1 Then
									FixCell(Row, "kimlik", Rss("kimlik"), "Kimlik numarası düzeltildi.")
									AddRssno(Rss)
									Corrected = True
								End If
							End If
							If Not Corrected Then
								Dim Rsk = Sigortali.KimlikAra(Local, kimlik)
								If Not Rsk.EOF AndAlso Difference(Trim(Rsk("adi")) & " " & Trim(Rsk("soyadi")), adi) < 0.1 Then
									FixCell(Row, "sno", Rsk("sno"), "Sigorta numarası düzeltildi.")
									AddRssno(Rsk)
									Corrected = True
								End If
							End If
							If Not Corrected Then
								Dim Rsa = Sigortali.AdSoyadAra(Local, adi)
								If Not Rsa.EOF AndAlso Difference(Trim(Rsa("adi")) & " " & Trim(Rsa("soyadi")), adi) < 0.1 Then
									FixCell(Row, "sno", Rsa("sno"), "Sigorta numarası düzeltildi.")
									FixCell(Row, "kimlik", Rsa("kimlik"), "Kimlik ve sigorta numarası düzeltildi.")
									AddRssno(Rsa)
									Corrected = True
								End If
							End If
							If Not Corrected Then
								Dim f = (From g In sigc Where adi.StartsWith(g.adi) AndAlso (g.kimlik = kimlik Or g.sno = sno))
								If f.Any Then
									If sno <> f.First.sno AndAlso kimlik <> f.First.kimlik Then
										FixCell(Row, "sno", f.First.sno, "Sigorta numarası düzeltildi.")
										FixCell(Row, "kimlik", f.First.sno, "Kimlik ve sigorta numarası düzeltildi.")
										Corrected = True
									ElseIf sno <> f.First.sno Then
										FixCell(Row, "sno", f.First.sno, "Sigorta numarası düzeltildi.")
										Corrected = True
									Else
										FixCell(Row, "kimlik", f.First.kimlik, "Kimlik numarası düzeltildi.")
										Corrected = True
									End If
								End If
							End If
						Case "invalid.pogs.0"
							If EkMesai Then
								FixCell(Row, "pogs", 0, "PÖGS 0 olmalıdır.")
								Corrected = True
							End If
						Case "invalid.pogs.30"
							FixCell(Row, "pogs", 30, "PÖGS en fazla 30 olabilir.")
							Corrected = True
						Case "pogs.overflow"
							FixCell(Row, "pek", Row.Cells("pek").Value / Row.Cells("pogs").Value * Items(1), "")
							FixCell(Row, "pogs", CDec(Items(1)), "PÖGS en fazla " & Items(1) & " olabilir.")
							Corrected = True
						Case "pek.underflow"
							FixCell(Row, "pek", CDec(Items(1)), "PEK en az " & Items(1) & " olmalıdır.")
							Corrected = True
						Case "pek.overflow"
							FixCell(Row, "pek", CDec(Items(1)), "PEK en fazla " & Items(1) & " olmalıdır.")
							Corrected = True
					End Select
					If Corrected Then Row.Cells("correct").Value = True : Row.Visible = True
				Next r
				If Modal.List.RowCount = 0 Then
					Warning("Düzeltilecek kayıt bulunmadı.")
					Close()
					Return
				End If
				Modal.Buttons.Show("Next")
				Modal.Help = "Düzeltilmesini istemediğiniz kayıtların işaretlerini kaldırın."
			Case EventType.Save
				For Each Row In (From r As DataGridViewRow In Modal.List.Rows Where r.Cells("correct").Value)
					Dim sirano = Row.Cells("sirano").Value
					For Each Item In Split(Mid(Row.Tag, 2), ",")
						If Item <> "" Then
							Grid1.Rows(sirano - 1).Cells(Item).Value = Row.Cells(Item).Value
							If Item = "sno" Then
								Dim Rs = Sigortali.SnoAra(Remote, Row.Cells(Item).Value)
								If Not Rs.EOF Then AddRssno(Rs)
							End If
						End If
					Next
					CheckRow(Grid1.Rows(sirano - 1))
				Next
				UpdateSummary()
				Close()
		End Select
	End Sub

	Sub FixCell(Row As DataGridViewRow, Column As String, Value As Object, Descr As String)
		Row.Cells(Column).Value = Value
		Row.Cells("durum").Value = "[!]"
		Row.Cells(Column).Style.BackColor = Color.Yellow
		Row.Cells("aciklama").Style.ForeColor = Color.Blue
		Row.Cells("aciklama").Value = Descr
		Row.Tag &= "," & Column
	End Sub

#End Region

#Region " Levenshtein "

	Function Difference(S1 As String, S2 As String) As Double
		Return LevenshteinDistance(S1, S2) / ((S1.Length + S2.Length)) / 2
	End Function

	Function LevenshteinDistance(S1 As String, S2 As String) As Integer
		Dim d(S1.Length, S2.Length) As Integer
		For i = 0 To S1.Length
			d(i, 0) = i
		Next i
		For j = 0 To S2.Length
			d(0, j) = j
		Next j
		For j = 1 To S2.Length
			For i = 1 To S1.Length
				d(i, j) = If(S1.Mid(i, 1).ToUpper = S2.Mid(j, 1).ToUpper, d(i - 1, j - 1), Math.Min(Math.Min(d(i - 1, j) + 1, d(i, j - 1) + 1), d(i - 1, j - 1) + 1))
			Next
		Next
		Return d(S1.Length, S2.Length)
	End Function

#End Region

#Region " Kapak bilgileri "

	Dim FileInfo As New Summary
	Dim ValidInfo As New Summary
	Dim Oran As New Oranlar

	Class Summary
		Friend Count As Integer
		Friend ToplamPogs As Decimal
		Friend ToplamPek As Decimal
		Friend SigortaliTutar As Double
		Friend IsverenTutar As Double
		Friend PrimTahakkuk As Double
		Friend CezaTutar As Double
		Friend ToplamTutar As Double
		Friend ErrorCount As Integer
		Friend WarningCount As Integer
	End Class

	Class Oranlar
		Public Sigortali As Double
		Public Isveren As Double
		Public Toplam As Double
		Public Ceza As Double
	End Class

	Sub PrepareSummaryPanel()
		Browser = New LightBrowser
		Browser.Dock = DockStyle.Fill
		List.LeftPanel.Controls.Add(Browser)
	End Sub

	Dim Browser As New LightBrowser

	Sub UpdateSummary()
		Select Case Tab
			Case 0 : UpdateSummaryKurum()
			Case 1 : UpdateSummaryKisi()
		End Select
	End Sub

#End Region

#Region " Emanet "

	Shadows WithEvents DataWindow As DataWindow

	Private Sub DialogEmanet(e As ProcessEventArgs)
		Select Case e.EventType
			Case EventType.Initialize
				Modal.Start("Emanet bilgileri", "Emanet bilgilerini girin.")
				Modal.AddDataWindow()
				Modal.DataWindow.Columns = 1
				'Modal.DataWindow.Rate = 0.33
				Modal.DataWindow.FieldPadding = 2
				Modal.CustomSize = New Size(360, 200)
				DataWindow = Modal.DataWindow
			Case EventType.Shown
				DataWindow.AddField("Emanet fiş no.", "emanetfisno")
				DataWindow.AddField("Emanet yılı", "emanetyil")
				DataWindow.AddField("Emanet tar.", "*emanettar")
				DataWindow.AddField("Toplam miktar", "*toplam", "m")
				DataWindow.AddField("Kalan miktar", "*kalan", "m")
				If DataWindow.Fields("emanetyil").IsEmpty Then DataWindow.Fields("emanetyil").Value = Today.Year
				Modal.Buttons.Show("Next")
			Case EventType.Save
				If Not OkunanEmanet Is Nothing Then
					Emanet = OkunanEmanet
				End If
				UpdateSummary()
				Modal.Close()
		End Select
	End Sub

	Dim Emanet As EmanetInfo

	Class EmanetInfo

		Public Tarih As Date
		Public EmanetNo As Integer
		Public Miktar As Decimal
		Public Kalan As Decimal

		Function Oku(Token As Token, yil As Integer, tahsilno As Integer) As Boolean
			Dim Rs = Kasa.EmanetOku(Token, yil, tahsilno)
			If Rs.EOF Then
				Warning("Emanet numarası bulunamadı")
				Return False
			End If
			Rs.MoveLast()
			EmanetNo = tahsilno
			Tarih = Rs("tahsiltar")
			Miktar = Rs("emanmikt")
			Kalan = Rs("emanmikk")
			Return True
		End Function

		Sub Refresh(Token As Token)
			Oku(Token, Tarih.Year, EmanetNo)
		End Sub

	End Class

	Dim OkunanEmanet As EmanetInfo

	Private Sub DataWindow_FieldValidating(Control As TextBoxBase, e As System.ComponentModel.CancelEventArgs) Handles DataWindow.FieldValidating
		If DataWindow.Fields("emanetyil").IsEmpty OrElse DataWindow.Fields("emanetfisno").IsEmpty Then
			OkunanEmanet = Nothing
			DataWindow.Fields("emanettar").Value = ""
			DataWindow.Fields("toplam").Value = ""
			DataWindow.Fields("kalan").Value = ""
			Return
		End If
		If Not Control.IsDirty Then Return
		OkunanEmanet = New EmanetInfo
		OkunanEmanet.Oku(Local, DataWindow.Fields("emanetyil").Value, DataWindow.Fields("emanetfisno").Value)
		DataWindow.Fields("emanettar").Value = OkunanEmanet.Tarih
		DataWindow.Fields("toplam").Value = Fm(OkunanEmanet.Miktar)
		DataWindow.Fields("kalan").Value = Fm(OkunanEmanet.Kalan)
	End Sub

#End Region

	Private Sub DeleteRow()
		List.Rows.Remove(List.CurrentCell.OwningRow)
		If List.Rows.Count = 0 Then List.AddRow()
		UpdateSummary()
	End Sub

End Class

